//
// Created by Langingsing on 2021/10/24.
//

#ifndef PROJ_STACK_H
#define PROJ_STACK_H

#include "Linear.h"

template<typename T>
class Stack : public Linear<T>
{
public:
    Stack() = default;

    /// 入栈，返回是否入栈成功
    inline bool push(T item);

    /// 出栈，返回弹出的值，若栈为空，抛出错误
    inline T pop();

    /// 获取栈顶元素的值，若栈为空，抛出错误
    inline T top() const;
};

template<typename T>
bool Stack<T>::push(T const item)
{
    if (Stack<T>::_full()) { // 满了
        const bool success = Stack<T>::_expandCapacity(); // 扩容

        if (!success) // 扩容失败
            return false;
    }

    Stack<T>::_basePtr[Stack<T>::_size++] = item; // 只有当 1.没满 或 2.满了且扩容成功 才会执行此行
    return true;
}

template<typename T>
inline T Stack<T>::pop()
{
    if (Stack<T>::empty()) {
        const std::string msg = "no item for pop()";
        throw std::out_of_range(msg);
    }

    return Stack<T>::_basePtr[--Stack<T>::_size];
}

template<typename T>
inline T Stack<T>::top() const
{
    if (Stack<T>::empty()) {
        const std::string msg = "no item for top()";
        throw std::out_of_range(msg);
    }

    return Stack<T>::_basePtr[Stack<T>::_size - 1];
}

#endif //PROJ_STACK_H
